/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package component;

import Helper.FileHelper;
import Helper.TimerHelper;
import controlP5.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import processing.core.PApplet;
import ddf.minim.*;


/**
 *
 * @author Caliste
 */
public class RightJogPart {
    
    public static String PATH_FILE_FOLDER = "C:\\Users\\Caliste\\Music\\House\\";
    //public static String PATH_FILE_FOLDER = "/home/biron/Music/Disiz-Transe-Lucide-FR-2014-SO/";
    
    private PApplet         _app;
    private Minim           _minim;

    private Button      _btnStop;
    private Toggle      _btnPlayAndPause;
    private ListBox     _lbListFiles;
    private Slider      _sliderVolume;
    
    private Textlabel   _tlFileSelected;
    private File        _fileSelected;
    private String      _filePath;
    private File[]      _files;

    private RightSoundProgressBar _spb;
    private RightTurntable _platine;
    private AudioPlayer _player;
    private SoundTimer _soundTimer;
    private int _playerState;
    private boolean _playerIsStopped;
    private String _timerCallbackInfo;
   
    /**
     * Ctor
     * @param mainApp 
     */
    public RightJogPart(PApplet mainApp)
    {
        _app = mainApp;
        ControlP5 controlP5 = new ControlP5(_app);
        _spb = new RightSoundProgressBar(_app, controlP5);
        _minim = new Minim(_app);
        
        // Création bouton 'Stop'
        _btnStop = controlP5.addButton("RightStop");
        _btnStop.setSize(50, 20);
        _btnStop.setPosition(470, 500);
        
        // Création bouton 'Play/Pause'
        _btnPlayAndPause = controlP5.addToggle("RightPlay");
        _btnPlayAndPause.setSize(50, 20);
        _btnPlayAndPause.setPosition(550, 500);
        
        // Création de la liste qui contiendra les tracks
        _lbListFiles = controlP5.addListBox("RightListe");
        _lbListFiles.setSize(250, 100);
        _lbListFiles.setPosition(420, 50);
        
        // Création d'un champs label pour afficher le track joué (ou sélectionné?)
        _tlFileSelected = controlP5.addTextlabel("RightlbFileSelected");
        _tlFileSelected.setSize(100, 80);
        _tlFileSelected.setPosition(420, 200);
        
        // Créaion du slider de volume
        //addSlider(theName, theMin, theMax, theX, theY, theWidth, theHeight);
        _sliderVolume = controlP5.addSlider("RightVolume", 0, 100, 650, 280, 30, 100);
        
        _platine = new RightTurntable(430, 225, 200, 200, _app);
        
        initListFiles(PATH_FILE_FOLDER);
        
        ListBox rightListFiles = getLbListFiles();

        if(rightListFiles != null)
        {
            String defautFilename = rightListFiles.getItem(0).getText();
            System.out.println("Default file selected : " + defautFilename);
            // on set la valeur du nom du fichier qui sera chargé
            SetValueFilenameSelected(defautFilename);
            // On charge dans le player le fichier 
  
            _player    = _minim.loadFile(getPathFilenameSelected());
            _soundTimer = new SoundTimer(_app, _player, getTlSoundTimer()); 
        }
    }
    
    /**
     * Rempli la liste des tracks
     * @param path 
     */
    private void initListFiles(String path)
    {
        // Lister les noms des contenus du répertoire courant
        _files              = new java.io.File(path).listFiles();
        List listFilename   = new ArrayList();
        List listFiles      = new ArrayList<File>();
 
        for (int i=0; i<_files.length; i++)
        {
            File file = _files[i];
            String ext = FileHelper.GetFileExtension(file);
            // Afficher le nom de chaque élément
            
            // On vérifie que l'extension est bien au format .mp3
            if(ext.equals(".mp3"))
            {
                String filename = file.getName();
                
                // Si le nom du fichier dépasse 50 caractères
                // On ne garde que les 50 premier
                if(filename.length() > 50)
                {
                    filename = filename.substring(0, 50);
                }
                
                listFilename.add(filename);
                listFiles.add(file);
            }
	}

        getLbListFiles().addItems(listFilename, 0);
    }

    /**
     * @return the _lbListFiles
     */
    public ListBox getLbListFiles() {
        return _lbListFiles;
    }
    
    /**
     * Permet de mettre a jour la valeur du label
     * indiquant le fichier selectionné.
     * @param value 
     */
    public void SetValueFilenameSelected(String value)
    {
        _tlFileSelected.setValue(value);
        _filePath = RightJogPart.PATH_FILE_FOLDER + value;
    }
    
    public String getValueFilenameSelected()
    {
        String filename = _tlFileSelected.getStringValue();
        return filename;
    }
    
    public String getPathFilenameSelected()
    {
        String filePath = RightJogPart.PATH_FILE_FOLDER + _tlFileSelected.getStringValue();
        return filePath;
    }

    /**
     * Recupere la valeur de bouton play
     * "1" pour play et "0" pour pause.
     * @return int
     */
    public int getValueBtnPlayAndPause() {
        return (int)_btnPlayAndPause.getValue();
    }

    /**
     * Cette methode permet de mettre a jour
     * la nouvelle valeur du bouton play.
     * @param value
     */
    public void setBtnValuePlayAndPause(int value) {
        _btnPlayAndPause.setValue(value);
    }

    /**
     * Cette methode retourne
     * le composant Textlabel associer
     * au soundTimer. Afin de mettre
     * a jour la valeur en fonction du temps restant
     * du piste en lecture.
     * @return the _tlSoundTimer
     */
    public Textlabel getTlSoundTimer() {
        return _spb.getTlSoundTimer();
    }

    /**
     * @return the _timeLine
     */
    public Slider getTimeLine() {
        return _spb.getTimeLine();
    }

    /**
     * @param _timeLine the _timeLine to set
     */
    public void setRangeTimeLine(float f, float f1) {
        _spb.setRangeTimeLine(f, f1);
    }

    /**
     * Cette methode retourne l'objet platine
     * @return the _platine
     */
    public RightTurntable getPlatine() {
        return _platine;
    }
    
    public void controlEvent(ControlEvent event) 
    {
        // Pour le slider volume
        if(event.getName().equals("RightVolume"))
        {
            float vol = event.getController().getValue();
            System.out.println("Le volume est de : " + (int) vol);
            if(_player != null)
            {
//                boolean hasVolume = _player.hasControl(Controller.VOLUME);
//                float dd = _player.getGain();
//                //System.out.println("GAIN : " + dd);
//                
//                if(hasVolume)
//                {
//                    _player.setVolume(vol);
//                } 
//                else
//                {
//                    _player.setGain(vol);
//                    
//                    dd = _player.getGain();
//                    //System.out.println("GAIN AFTER : " + dd);
//                }
            }
        }
        
        if(event.isGroup() && event.getName().equals("RightListe"))
        {
            // on recup l'index (position) du fichier
            int indexFile           = (int)event.getValue();
            // On récupère la liste de fichiers musicaux
            ListBox listComponent   = getLbListFiles();
            // on récupère le nom du fichier selectionné
            String filename         = listComponent.getItem(indexFile).getName();
            // Et avec, on set la valeur du label qui affiche le nom du fichier séléctionné
            SetValueFilenameSelected(filename);
            System.out.println("Fichier selectionné : " +  filename);
            
            // Si le player est en train de jouer
            if(_player != null && _player.isPlaying())
            {
                // on set la 'valeur' du bouton play/pause à 0
                setBtnValuePlayAndPause(0);
                // on arrete la lecture
                _minim.stop();
                getPlatine().Stop();
            }
            
            // on charge dans le player le fichier grace à son nom (qui à été séléctionné)
            _player = _minim.loadFile(getPathFilenameSelected());
            _soundTimer = new SoundTimer(_app, _player, getTlSoundTimer());
            
//            _play = new ButtonPlay(250, 130, 20, 10, this, _player);
//            _rewind = new ButtonRewind(500/2, 130, 20, 10, this, _player);
//            _ffwd = new ButtonForward(500/2 , 130, 20, 10, this, _player);
        }
        
        // Pour le bouton play/pause
        if(event.getName().equals("RightPlay"))
        {
            int value = (int) event.getController().getValue();
            boolean isPlaying = _player.isPlaying();
            // si on est en 'pause', ou en 'stop', autrement dit, si aucune musique n'est jouée
            if(_playerState == 0 && (!isPlaying || _playerIsStopped))
            {
                if(value == 1)
                {
                    _player = _minim.loadFile(getPathFilenameSelected());
                    _playerIsStopped = false;
                    // On lance le track ('play')
                    _player.play();

                    _soundTimer = new SoundTimer(_app, _player, getTlSoundTimer());
                    _soundTimer.start();
                    getPlatine().Play();
                }
            }
            else
            {
                if(_playerState == 0)
                {
                    _player.pause();
                    _playerState = 1;
                    _soundTimer.stop();
                    getPlatine().Stop();
                }
                else
                {
                    _player.play();
                    _playerState = 0;
                    _soundTimer.start();
                    getPlatine().Play();
                }
            }
        }
        
        // Pour le bouton 'Stop'
        if(event.getName().equals("RightStop"))
        {
            System.out.println("arret le mode play");
            
            if(_player != null && _player.isPlaying())
            {
                _playerIsStopped = true;
                System.out.println("btnStop : " + _playerIsStopped);
                _minim.stop();
                setBtnValuePlayAndPause(0);
                _soundTimer.stop();
                _soundTimer.clearValueTlTimer();
                getPlatine().Stop();
            }
        }
    }
    
    public void onTickEvent(int timerId, long timeLeftUntilFinish) 
    {
        _timerCallbackInfo = TimerHelper.GetTimeFormat(timeLeftUntilFinish);
        _soundTimer.setValueTlTimer(_timerCallbackInfo);
        setRangeTimeLine((timeLeftUntilFinish - _soundTimer.getLength()), _soundTimer.getLength());
    }

    public void onFinishEvent(int timerId) 
    {
        _timerCallbackInfo = "[finished]";
        _soundTimer.setValueTlTimer(_timerCallbackInfo);
    }
}
